package com.springboot.service.jubt;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Classname JubtSpider
 * @Description TODO
 * @Version 1.0.0
 * @Date 2025/2/8 14:33
 * @Author by zyj
 */
public class JubtSpider  implements PageProcessor {
    static String indexUrl = "https://dh.mnxz.fun/cn/index.html";
    static String baseUrl = "https://dh.mnxz.fun/cn/";

    // 站点配置
    private Site site = Site.me()
            .setRetryTimes(1) // 重试次数
            .setSleepTime(1000) // 抓取间隔
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36");

    @Override
    public void process(Page page) {
        Html html = page.getHtml();
//        System.out.println("html:"+html);
        // 提取导航条目（假设条目位于 class="nav-item" 的 div 中）
        List<String> navItems = html.xpath("//ul[@class='main-menu']/li").all();
//        System.out.println("navItems:"+navItems.size());
        JSONArray mainContent = new JSONArray();
        for(String mainMenu: navItems){
            JSONObject mainJsonObj = new JSONObject();
            Html mainMenuHtml = new Html(mainMenu);
            String menuHrefUl = mainMenuHtml.xpath("//ul").get();
            String mainName = mainMenuHtml.xpath("//a/span/text()").get();
            if(menuHrefUl!=null && !menuHrefUl.isEmpty()){
                mainJsonObj.set("name", mainName);
                mainJsonObj.set("en_name", mainName);
                mainJsonObj.set("icon", "linecons-lightbulb");
                JSONArray childrenArray = new JSONArray();

                Html menuHrefUls = new Html(menuHrefUl);
                List<String> menuHrefUlLi = menuHrefUls.xpath("//li").all();
                for(String clidrenHtmlString: menuHrefUlLi){
                    Html clidrenHtml = new Html(clidrenHtmlString);
                    String isHot = clidrenHtml.xpath("//a/span[@class='label label-pink pull-right hidden-collapsed']").get();
                    String childrenName = clidrenHtml.xpath("//a/span[@class='title']/text()").get();
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.set("name", childrenName);
                    jsonObject.set("en_name", childrenName);
                    jsonObject.set("is_hot", StrUtil.isNotEmpty(isHot));
                    jsonObject.set("icon", "linecons-star");
                    JSONArray content = content(clidrenHtml, page);
                    if(content==null || content.isEmpty()){
                        continue;
                    }
                    jsonObject.set("web",content);
                    childrenArray.add(jsonObject);
                }
                mainJsonObj.set("children", childrenArray);
                mainContent.add(mainJsonObj);
            }else {
                String isHot = mainMenuHtml.xpath("//a/span[@class='label label-pink pull-right hidden-collapsed']").get();
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("name", mainName);
                jsonObject.set("en_name", mainName);
                jsonObject.put("is_hot", StrUtil.isNotEmpty(isHot));
                jsonObject.set("icon", "linecons-star");
                JSONArray content = content(mainMenuHtml, page);
                if(content==null || content.isEmpty()){
                    continue;
                }
                jsonObject.set("web", content);
                mainContent.add(jsonObject);
            }
        }


//        System.out.println("navItems2:"+navItems2);
//        List<NavItem> results = new ArrayList<>();
//        for (String item : navItems) {
//            Html itemHtml = new Html(item);
//            System.out.println("item1:"+itemHtml);
//            // 提取标签、名称、描述、地址
//            String tag = itemHtml.xpath("//div[@class='tag']/text()").get();
//            String name = itemHtml.xpath("//a/text()").get();
//            String url = itemHtml.xpath("//a/@href").get();
//            String description = itemHtml.xpath("//p[@class='description']/text()").get();
//
//            // 提取 Logo（假设通过 Favicon 服务生成）
//            String logoUrl = "https://www.google.cn/s2/favicons?domain=" + url;
//
//            // 封装为对象
//            NavItem navItem = new NavItem(tag, name, url, description, logoUrl);
//            results.add(navItem);
//        }

        // 保存结果
        page.putField("results", mainContent);
//        System.out.println("children:"+children.toString());
    }

    public JSONArray content(Html mainMenuHtml,Page page ){
        String name = mainMenuHtml.xpath("//a//span/text()").get();
        String menuHref = mainMenuHtml.xpath("//a/@href").all().get(0);

        if(name.contains("置顶推荐") || name.contains("聚BT友站")){
            return null;
        }
        Request request = null;
//            System.out.println("mainMenu:"+mainMenu);

        if(menuHref.contains(".html#")){
            // 创建新的Request对象
            request = new Request(baseUrl+menuHref);
        } else {
            // 创建新的Request对象
            request = new Request(indexUrl+menuHref);
        }
        // 可以为每个请求设置额外的参数或headers等
        // request.putExtra("someKey", "someValue");
        page.addTargetRequest(request);
        Html html2 = page.getHtml();
//        System.out.println("html2:"+html2);
        List<String> navItems2 = html2.xpath("//div[@class='main-content']").all();
        Document doc = Jsoup.parse(navItems2.get(0));
        // 查找第一个<h4>标签
        // 获取所有class为text-gray的h4标签
        Elements h4Elements = doc.select("h4.text-gray");

        Element targetH4 = null;
        for (Element h4 : h4Elements) {
            // 在每个h4标签内查找id为惺惺惜惺惺的i标签
//            System.out.println("menuHref:"+menuHref);
            String id = menuHref.split("#").length>1?menuHref.split("#")[1]:name;
            Element specificITag = h4.selectFirst("i[id="+id+"]");

            if (specificITag != null) {
                targetH4 = h4;
                break; // 找到后退出循环
            }
        }
//        if(menuHref.contains("磁力搜索")){
//            System.out.println("xxxxx");
//        }
        // 如果需要提取两个h4之间的内容
        StringBuilder contentBetweenH4s = new StringBuilder();
        if (targetH4 != null) {
//            System.out.println("Found the h4 containing the i tag with id "+menuHref);

            // 开始遍历从targetH4之后的兄弟节点
            Element sibling = targetH4.nextElementSibling();
            while (sibling != null && !sibling.tagName().equalsIgnoreCase("h4")) {
                contentBetweenH4s.append(sibling.outerHtml()).append("\n");
                sibling = sibling.nextElementSibling();
            }

            // 输出结果
//            System.out.println("Content between the specified h4 and the next h4:\n" + contentBetweenH4s.toString());
        } else {
//            System.out.println("The i tag with id "+menuHref+" was not found in any h4.");
        }

        if(contentBetweenH4s==null||contentBetweenH4s.isEmpty()){
            return null;
        }

        // 使用Jsoup选择器找到包含特定文本的<h4>标签
        JSONArray webs = new JSONArray();
        Html webHtml = new Html(contentBetweenH4s.toString());
        List<String> webList= webHtml.xpath("//div[@class='col-sm-3']").all();
        for (String webhtmlStr : webList) {
//                    System.out.println("Found div content:"+nextDiv.html());
                Html html3 = new Html(webhtmlStr.toString());
                List<Selectable> all = html3.xpath("//div[@class='xe-widget xe-conversations box2 label-info']").nodes();
                for(Selectable selectable: all){
                    JSONObject web = new JSONObject();
                    String string = selectable.xpath("//div[@class='xe-widget xe-conversations box2 label-info']/@onclick").toString();
                    String title = regixTitle(selectable.xpath("//div[@class='xe-widget xe-conversations box2 label-info']//a[@class='xe-user-name overflowClip_1']//strong").get());
                    String desc = selectable.xpath("//div[@class='xe-widget xe-conversations box2 label-info']//p[@class='overflowClip_2']/text()").toString();
                    String url = regixUrl(string);
                    if(StrUtil.isBlank(url)){
                        continue;
                    }
                    web.put("url", url);
                    web.put("logo", "");
                    web.put("title", title);
                    web.put("desc", desc);
                    webs.add(web);
                }


        }
        return webs;
    }

    public  String regixTitle(String titleContent) {
        Pattern pattern = Pattern.compile("<strong[^>]*>(\\s*<p[^>]*>(.*?)</p>\\s*|\\s*(.*?)\\s*)</strong>", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(titleContent);

        while (matcher.find()) {
            // 如果有<p>标签，则取其内容
            if (matcher.group(2) != null) {
//                System.out.println(matcher.group(2).trim());
                return matcher.group(2).trim();
            }
            // 如果没有<p>标签，则直接取<div>的内容
            else if (matcher.group(3) != null) {
//                System.out.println(matcher.group(3).trim());
                return matcher.group(3).trim();
            }
        }
        return null;
    }

    public  String regixUrl(String input) {

        // 定义正则表达式模式，用于匹配myopener函数内的第一个参数
        String regex =  "myopener\\(\"([^\"]+)\", \"_blank\"\\)";

        // 编译正则表达式

        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);

        // 创建matcher对象
        Matcher matcher = pattern.matcher(input);

        // 查找匹配的部分
        if (matcher.find()) {
            // 提取并打印匹配到的URL
            String group = matcher.group(1);
            if(group.contains("https://") || group.contains("http") || group.contains("www")){
                return group;
            }
//            System.out.println("Extracted URL: " + matcher.group(1));

        } else {
//            System.out.println("No match found.");
        }

        return null;
    }

    @Override
    public Site getSite() {
        return site;
    }

    public static void main(String[] args) {
        // 创建自定义 Pipeline
        SingleJsonFilePipeline pipeline = new SingleJsonFilePipeline("D:\\data\\webmagic\\output.json");
        // 启动爬虫
        Spider.create(new JubtSpider())
                .addUrl(indexUrl) // 起始 URL
                .addPipeline(pipeline) // 保存为 JSON 文件
                .thread(5) // 线程数
                .run();
        pipeline.close();
    }
}
